import Mermaid from "@theme/Mermaid";

# assertNotNull

:::info Advanced

It's rare that this is needed; most steps can handle a `null` input and know
whether or not they should continue to process the value.

:::

Guard a step so that `null` values become execution errors. The returned step
shares the same value as the original when it yields a non-null result. If the
wrapped step yields `null`, Gra*fast* raises a `SafeError`
with the message you provide, and any dependant steps are thereby prevented from
running for this value.

:::note[Declarative flow]

Only dependants of the returned step see the assertion. Other branches of the
plan continue executing.

:::

## Example

```ts
const spec = specFromNodeId(userHandler, $id);
// `spec.id` is a step representing the database ID if `$id` is a valid user ID,
// or yields `null` otherwise. Throw if `null`.
const $databaseId = assertNotNull(spec.id, "Expected a User ID");
const $user = loadOne($databaseId, batchGetUserById);
```

## Trapping

Use [`trap`](./trap.mdx) when you need to turn the resulting error back into data
(such as a `null`, or perhaps the error as a data value).

## Plan diagrams

Internally, `assertNotNull` currently builds a `__FlagStep`, but that step is
usually converted into a dependency constraint when another step depends on it.
Thus in plan diagrams it's more common to see it on the dependency edge:
instead of a visible node, you will see the dependency arrow annotated with
labels such as `rejectNull`.

<Mermaid chart={`
graph TD
  A["Access"] -->|"rejectNull;onReject=”Error: Expected a User ID”"| B["LoadOne"]
`} />

## Advanced

Optionally pass `{ if: $cond }` to toggle the assertion dynamically. When the
condition yields `false`, `assertNotNull` behaves like a pass-through. See
[`inhibitOnNull`](./inhibitOnNull) for a similar example.
